package config

import (
	"fmt"
	"github.com/chmodke/gitmm/log"
	"github.com/chmodke/gitmm/util"
	"github.com/spf13/viper"
	"os"
	"path/filepath"
)

var viperConfig *viper.Viper

func Load(configName string) (*viper.Viper, error) {
	if configName == "" {
		return nil, fmt.Errorf("config name is empty")
	}
	viper.SetConfigName(configName)
	viper.SetConfigType("yaml")
	viper.AddConfigPath("./")
	viper.AddConfigPath("../")

	if err := viper.ReadInConfig(); err != nil {
		if _, ok := err.(viper.ConfigFileNotFoundError); ok {
			return nil, fmt.Errorf("config file.go %s.%s not found", configName, "yaml")
		} else {
			return nil, err
		}
	}

	viperConfig = viper.GetViper()
	return viperConfig, nil
}

func LoadConfig() *Config {
	var err error
	viperConfig, err = Load("repo")
	log.Printf("Config File Used %v.\n", viper.ConfigFileUsed())
	if err != nil {
		log.Consoleln(err)
		log.Consoleln("可以执行`gitmm config`命令生成示例配置文件。")
		os.Exit(1)
	}

	var config Config
	if err = viper.Unmarshal(&config); err != nil {
		fmt.Println(err.Error())
		return nil
	}

	if !config.DefineRemote("origin") {
		log.Consoleln("未配置origin远端地址")
		os.Exit(1)
	}
	if !config.DefineRemote("upstream") {
		log.Consoleln("未配置upstream远端地址")
		os.Exit(1)
	}
	return &config
}

func WriteSample() {
	sample := viper.New()
	var remotes = []Remote{
		{"origin", "https://gitee.com", DEFAULT_REPO_TPL},
		{"upstream", "https://github.com", DEFAULT_REPO_TPL},
	}
	sample.Set("remotes", remotes)

	var repos = []Repo{
		{Name: "gitmm", Path: "/chmodke/gitmm", Local: "golang/gitmm", Branch: "master", Remote: "origin"},
		{Name: "remote_exec", Path: "/chmodke/remote_exec", Local: "golang/remote_exec", Branch: "master", Remote: "origin"},
	}
	sample.Set("repos", repos)

	sample.WriteConfigAs("repo_sample.yaml")
}

func WriteCfg(config *Config, path string) {
	file := viper.New()
	file.Set("remotes", config.Remotes)
	file.Set("repos", config.Repos)

	if err := os.MkdirAll(path, 0750); err != nil {
		log.Printf(err.Error())
		return
	}

	filePath := filepath.Join(path, "repo.yaml")
	if util.PathExists(filePath) {
		os.Remove(filePath)
	}
	if err := file.WriteConfigAs(filePath); err != nil {
		log.Printf(err.Error())
		return
	}
}
